package com.xy.core.web;

import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.UrlPathHelper;

import com.xy.p2p.action.admin.TuserAction;
import com.xy.p2p.model.Trole;
import com.xy.p2p.model.Trolepermission;
import com.xy.p2p.model.Tuser;

/**
 * 
 * 权限过滤
 * 
 * 
 */
public class AdminContextInterceptor extends HandlerInterceptorAdapter {
	private static final Logger log = Logger
			.getLogger(AdminContextInterceptor.class);
	public static final String SITE_PARAM = "_site_id_param";
	public static final String SITE_COOKIE = "_site_id_cookie";
	public static final String PERMISSION_MODEL = "_permission_key";

	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		String uri = getURI(request);
		// 不在验证的范围内
		if (exclude(uri)) {
			return true;
		}
		// 获得用户
		Tuser user = (Tuser) request.getSession().getAttribute(TuserAction.AUTH_KEY);

		
		// 用户为null跳转到登陆页面
		if (user == null) {
			response.sendRedirect(getLoginUrl(request));
			return false;
		}

		// 没有访问权限，提示无权限。
		if (!isSuper(user)&&!permistionPass(uri, user.getTroles())) {
			request.setAttribute("messsage", "没有访问权限");
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return false;
		}
		return true;
	}
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler, ModelAndView mav)
			throws Exception {
		// 获得用户
		Tuser user = (Tuser) request.getSession().getAttribute(TuserAction.AUTH_KEY);

		// 不控制权限时perm为null，PermistionDirective标签将以此作为依据不处理权限问题。
		if (  user != null && !isSuper(user)&&  mav != null
				&& mav.getModelMap() != null && mav.getViewName() != null
				&& !mav.getViewName().startsWith("redirect:")) {
			Set<Trole> s=user.getTroles();
			Set s1=new HashSet();
			for(Trole t:s){
				Set s2=t.getTrolepermissions();
				s1.addAll(s2);
			}
			mav.getModelMap().addAttribute(PERMISSION_MODEL,s1);
		}
	}
	public boolean isSuper(Tuser user) {
		Set<Trole> roles = user.getTroles();
		if (roles == null) {
			return false;
		}
		for (Trole role : roles) {
			if (role.getIsSuper().equals("1")) {
				return true;
			}
		}
		return false;
	}
	 
	private String getLoginUrl(HttpServletRequest request) {
		StringBuilder buff = new StringBuilder();
		if (loginUrl.startsWith("/")) {
			String ctx = request.getContextPath();
			if (!StringUtils.isBlank(ctx)) {
				buff.append(ctx);
			}
		}
		buff.append(loginUrl).append("?");
		buff.append("returnUrl").append("=").append(returnUrl);

		return buff.toString();
	}

	private boolean exclude(String uri) {
		if (excludeUrls != null) {
			for (String exc : excludeUrls) {
				if (exc.equals(uri)) {
					return true;
				}
			}
		}
		return false;
	}

	private boolean permistionPass(String uri, Set<Trole> roles) {
		String u = null;
		int i;
		for (Trole role : roles) {
			Set<Trolepermission> perms = role.getTrolepermissions();
			for (Trolepermission perm : perms) {
				if (uri.startsWith(perm.getUri())) {
					return true;
				}
			}
		}
		System.out.println("no permistion:"+uri);
		//测试
		return false;
	}

	/**
	 * 获得第三个路径分隔符的位置
	 * 
	 * @param request
	 * @throws IllegalStateException
	 *             访问路径错误，没有三(四)个'/'
	 */
	private static String getURI(HttpServletRequest request)
			throws IllegalStateException {
		UrlPathHelper helper = new UrlPathHelper();
		String uri = helper.getOriginatingRequestUri(request);
		String ctxPath = helper.getOriginatingContextPath(request);
		int start = 0, i = 0, count = 2;
		if (!StringUtils.isBlank(ctxPath)) {
			count++;
		}
		while (i < count && start != -1) {
			start = uri.indexOf('/', start + 1);
			i++;
		}
		if (start <= 0) {
			throw new IllegalStateException(
					"admin access path not like '/admin/xy/...' pattern: "
							+ uri);
		}
		return uri.substring(start);
	}

	private String[] excludeUrls;

	private String loginUrl;
	private String returnUrl;

	public void setExcludeUrls(String[] excludeUrls) {
		this.excludeUrls = excludeUrls;
	}

	public void setLoginUrl(String loginUrl) {
		this.loginUrl = loginUrl;
	}

	public void setReturnUrl(String returnUrl) {
		this.returnUrl = returnUrl;
	}

}